#ifndef MODBUSTRANSFER_H
#define MODBUSTRANSFER_H

/**
 * @copyright Copyright (c) 2025 
 * CSG Digital Grid Technology (Guangdong) Co., Ltd.
 * @author zhouyan
 * @brief modbus规约数据解析
*/
#include "sys_inc.h"
#include "dx_type.h"

typedef struct TagModbusCmdInfo
{
    uint8_t  dev_addr;              //访问的设备地址
    uint8_t  func_code;             //功能码
    uint16_t reg_addr;              //读取的寄存器起始地址
    uint16_t reg_num;               //读取的寄存器数量
    uint16_t expect_recv_size;      //期望收到的数据长度
    uint16_t order;                 //TCP的帧ID序号
} ModbusCmdInfo;

typedef struct TagModbusYKCmdInfo
{
    uint8_t  dev_addr;              //访问的设备地址
    uint8_t  func_code;             //功能码
    uint16_t reg_addr;              //寄存器起始地址
    uint16_t status;                //遥控命令值
    uint16_t expect_recv_size;      //期望收到的数据长度
    uint16_t order;                 //TCP的帧ID序号
} ModbusYKCmdInfo;

class ModbusTransferPrivate;
class IPhyLink;
class ModbusTransfer
{
public:
    enum Mode {
        RTU,
        TCP,
        RTU_CRC_HL
    };
    /**
     * @brief ModbusTransfer
     * @param dev
     * @param settings:  ModbusSettings指针，内部仅引用指针，需要外部传入全局变量
     * @param mode
     */
    ModbusTransfer(IPhyLink *dev, Mode mode=RTU);
    ~ModbusTransfer();

    bool isTcp(void) const;
    void setPhyLink(IPhyLink *dev);
    void setMode(Mode mode);
    int sendCmdAndRecv(const ModbusCmdInfo &cmd, uint8_t *recv_buf);
    int setYKCmd(const ModbusYKCmdInfo &cmd);
    uint8_t encode(const ModbusCmdInfo &cmd, uint8_t *buf, uint8_t buf_size);
    uint8_t encode(const ModbusYKCmdInfo &cmd, uint8_t *buf, uint8_t buf_size);
    int parseRTU(const uint8_t *rx_data, uint16_t rx_len, uint8_t slave_id, uint8_t func);
    bool verifyCRC(const uint8_t *rx_data, uint16_t rx_len);
private:
    ModbusTransferPrivate *private_;
};
#endif
